package com.yfp.org.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.NumberUtil;
import com.yfp.common.core.domain.R;
import com.yfp.common.core.domain.Response;
import com.yfp.common.core.domain.ResponseEnum;
import com.yfp.common.core.enums.PackageStatusEnums;
import com.yfp.common.core.enums.PayStatusEnum;
import com.yfp.common.core.enums.PayTypeEnum;
import com.yfp.common.core.exception.ServiceException;
import com.yfp.common.core.utils.StringUtils;
import com.yfp.common.security.utils.SecurityUtils;
import com.yfp.minapp.auth.api.RemoteClientService;
import com.yfp.operation.api.RemoteOperationService;
import com.yfp.org.domain.dto.*;
import com.yfp.org.domain.entity.*;
import com.yfp.org.enums.GoodsTypeEnum;
import com.yfp.org.mapper.*;
import com.yfp.org.service.OrderListService;
import com.yfp.system.api.RemoteRoleService;
import com.yfp.system.api.domain.SysRole;
import com.yfp.system.api.domain.SysUser;
import com.yfp.system.api.model.LoginUser;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.yfp.common.core.utils.PageUtils.startPage;

/**
 * 订单表(OrderList)表服务实现类
 *
 *
 * @since 2023-12-28 16:07:28
 */
@Service
@Slf4j
public class OrderListServiceImpl implements OrderListService {
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private OrderListMapper orderListMapper;
    @Value("${MiniProgram.RefundUrl}")
    private String refundUrl;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private SysUserCompanyMapper sysUserCompanyMapper;
    @Resource
    private CompanyMapper companyMapper;
    @Resource
    private RemoteClientService remoteClientService;
    @Resource
    private RemoteOperationService remoteOperationService;
    @Resource
    private TagComboMapper tagComboMapper;
    @Resource
    private RemoteRoleService remoteRoleService;

    /**
     * 通过ID查询单条数据
     *
     * @param orderSn 主键
     * @return 实例对象
     */
    @Override
    public HashMap<String, Object> queryById(String orderSn) {
        OrderDetail orderDetail = new OrderDetail();
        OrderList orderList1 = new OrderList();
        orderList1.setId(orderSn);
        OrderList orderList = orderListMapper.queryById(orderList1);
        orderDetail.setOrderDetailId(orderSn);
        List<OrderDetail> orderDetails = orderDetailMapper.queryAllByLimit(orderDetail);
        orderDetails.forEach(e -> {
            e.setApplietAmount(orderList.getAmt());
        });

        HashMap<String, Object> orderMap = new HashMap<>();
        if (orderList.getUpdateName() != null) {
            orderList.setExceptionOper(orderList.getUpdateName());
            orderList.setOrderEndTime(orderList.getUpdateTime());
        }
        orderMap.put("order", orderList);
        orderMap.put("orderDetails", orderDetails);
        return orderMap;
    }

    /**
     * 分页查询
     *
     * @param orderList 筛选条件
     * @return 查询结果
     */
    @Override
    public List<OrderList> queryByPage(OrderList orderList) {

        if (orderList.getType().equals("Exception")) {
            orderList.setIsExceptionOper("0");
        }
        if (orderList.getType().equals("refund")) {
            orderList.setIsExceptionOper("1");
            orderList.setNormalPayStatus(6);

        }
        if (orderList.getType().equals("normal")) {
            orderList.setIsExceptionOper("1");
        }

        // 根据标签id获取标签名称
        if (!BeanUtil.isEmpty(orderList) && null != orderList.getTagId()) {
            String tagName = tagComboMapper.selectTagName(orderList.getTagId());
            orderList.setTagName(tagName);
        }

        R<List<String>> roleCity = remoteRoleService.findRoleCity();
        List<String> cityNames = roleCity.getData();

        if (!CollUtil.isEmpty(cityNames)) {
            orderList.setCityNames(cityNames);
        }

        startPage();
        List<OrderList> orderLists = orderListMapper.selectAllLimit(orderList);
        return orderLists;
    }

    @Override
    public List<OrderList> getDeviceOrder(OrderList orderList) {

        if (orderList.getType().equals("Exception")) {
            orderList.setIsExceptionOper("0");
        }
        if (orderList.getType().equals("refund")) {
            orderList.setIsExceptionOper("1");
            orderList.setNormalPayStatus(6);

        }
        if (orderList.getType().equals("normal")) {
            orderList.setIsExceptionOper("1");
        }

        // 根据标签id获取标签名称
        if (!BeanUtil.isEmpty(orderList) && null != orderList.getTagId()) {
            String tagName = tagComboMapper.selectTagName(orderList.getTagId());
            orderList.setTagName(tagName);
        }

        R<List<String>> roleCity = remoteRoleService.findRoleCity();
        List<String> cityNames = roleCity.getData();

        if (!CollUtil.isEmpty(cityNames)) {
            orderList.setCityNames(cityNames);
        }

        startPage();
        List<OrderList> orderLists = orderListMapper.getDeviceOrder(orderList);
        return orderLists;
    }

    /**
     * 计算金额
     *
     * @param orderLists
     */
    public void calculate(List<OrderList> orderLists) {
        if (!orderLists.isEmpty()) {
            for (OrderList e : orderLists) {
                if (e.getCount() == null) {
                    e.setCount(0L);
                }
                BigDecimal bigDecimal = new BigDecimal(e.getCount());
                BigDecimal multiply = new BigDecimal(e.getAmt());
                BigDecimal multiply1 = multiply.multiply(bigDecimal);
                e.setAmt(String.valueOf(multiply1));
            }
        }
    }

    @Override
    public List<SalesRankingDTO> salesRanking() {
        return orderListMapper.salesRanking();
    }

    @Override
    public BigDecimal salesRealtime() {
        return orderListMapper.salesRealtime();
    }

    @Override
    public List<SalesTrendsDTO> salesTrends(DateTime lastStartOfWeek, DateTime endOfWeek) {
        return orderListMapper.salesTrends(lastStartOfWeek, endOfWeek);
    }

    @Override
    public List<ProductsTopSalesDTO> productsTopSales() {
        return orderListMapper.productsTopSales();
    }

    @Override
    public OrderTypeDTO getOrderTypeCount() {
        OrderList orderListMiniAppClient = new OrderList();
        orderListMiniAppClient.setOrderType("0");

        OrderList orderListDeviceClient = new OrderList();
        orderListDeviceClient.setOrderType("1");

        long miniAppClientNum = orderListMapper.count(orderListMiniAppClient);
        long deviceClientNum = orderListMapper.count(orderListDeviceClient);

        OrderTypeDTO orderTypeDTO = new OrderTypeDTO();
        orderTypeDTO.setMiniAppClientNum(miniAppClientNum);
        orderTypeDTO.setDeviceClientNum(deviceClientNum);
        return orderTypeDTO;
    }


    /**
     * 导出
     *
     * @param orderList
     * @return
     */
    @Override
    public List<OrderList> derive(OrderList orderList) {
        if (orderList.getType().equals("Exception")) {
            orderList.setIsExceptionOper("0");
        }
        if (orderList.getType().equals("refund")) {
            orderList.setIsExceptionOper("1");
            orderList.setNormalPayStatus(6);

        }
        if (orderList.getType().equals("normal")) {
            orderList.setIsExceptionOper("1");
        }

        // 根据标签id获取标签名称
        if (!BeanUtil.isEmpty(orderList) && null != orderList.getTagId()) {
            String tagName = tagComboMapper.selectTagName(orderList.getTagId());
            orderList.setTagName(tagName);
        }

        R<List<String>> roleCity = remoteRoleService.findRoleCity();
        List<String> cityNames = roleCity.getData();

        if (!CollUtil.isEmpty(cityNames)) {
            orderList.setCityNames(cityNames);
        }

        List<OrderList> orderLists = orderListMapper.selectAllLimit(orderList);
        return orderLists;
    }

    @Override
    public List<OrderList> exportDevOrderList(OrderList orderList) {
        if (orderList.getType().equals("Exception")) {
            orderList.setIsExceptionOper("0");
        }
        if (orderList.getType().equals("refund")) {
            orderList.setIsExceptionOper("1");
            orderList.setNormalPayStatus(6);

        }
        if (orderList.getType().equals("normal")) {
            orderList.setIsExceptionOper("1");
        }

        // 根据标签id获取标签名称
        if (!BeanUtil.isEmpty(orderList) && null != orderList.getTagId()) {
            String tagName = tagComboMapper.selectTagName(orderList.getTagId());
            orderList.setTagName(tagName);
        }

        R<List<String>> roleCity = remoteRoleService.findRoleCity();
        List<String> cityNames = roleCity.getData();

        if (!CollUtil.isEmpty(cityNames)) {
            orderList.setCityNames(cityNames);
        }

        List<OrderList> orderLists = orderListMapper.getDeviceOrder(orderList);
        return orderLists;
    }


    //    @Override
//    public List<OrderList> queryByPage(OrderList orderList) {
    public List<OrderList> dsfsfwd(OrderList orderList) {
//        Long userId = SecurityUtils.getUserId();
        Long userId = 58L;
        SysUserRoleKey sysUserRoleKey = new SysUserRoleKey();
        SysUser sysUser = userMapper.selectUserById(userId);
        List<SysUserRoleKey> sysUserRoleKeys = sysUserRoleMapper.selectByExample(sysUserRoleKey);
        List<SysUserRoleKey> list = sysUserRoleKeys.stream().filter(e -> e.getRoleId() == 1).toList();
        List<String> radius = sysUser.getRoles().stream().map(SysRole::getDataScope).collect(Collectors.toList());
        if (orderList.getType().equals("Exception")) {
            orderList.setIsExceptionOper("0");
        }
        if (orderList.getType().equals("refund")) {
            orderList.setIsExceptionOper("1");
            orderList.setNormalPayStatus(6);

        }
        if (orderList.getType().equals("normal")) {
            orderList.setIsExceptionOper("1");
        }

//        long count = orderListMapper.count(orderList);
        startPage();
        List<OrderList> orderLists = null;
        if (!list.isEmpty() || radius.contains("1")) {
            orderLists = orderListMapper.queryAllByLimit(orderList);
            for (OrderList e : orderLists) {
                BigDecimal bigDecimal = new BigDecimal(e.getCount());
                BigDecimal multiply = new BigDecimal(e.getAmt());
                BigDecimal multiply1 = multiply.multiply(bigDecimal);
                e.setAmt(String.valueOf(multiply1));
            }
            return orderLists;
        }
        if (radius.contains("3")) {
            boolean allParamsAreNotNull = Stream.of(orderList.getOrderTime(), orderList.getOrderEndTime(), orderList.getOrderSn(), orderList.getCompanyId(), orderList.getOrderType(), orderList.getTagId(), orderList.getComboName(), orderList.getPayStatus()).allMatch(Objects::isNull);
            if (allParamsAreNotNull) {
//                orderList.setCompanyId(sysUser.getCompanyId());
//                orderLists.addAll(orderListMapper.queryAllByLimit(orderList)) ;

                Company company = new Company();
                company.setParentId(sysUser.getCompanyId());
                List<Company> companies = companyMapper.queryAllByLimit(company);
                List<String> list1 = companies.stream().map(Company::getCompanyId).collect(Collectors.toList());
//                List<OrderList> finalOrderLists = orderLists;
                if (list1.isEmpty()) {
                    List<OrderList> orderLists1 = orderListMapper.queryLime(Collections.singletonList(sysUser.getCompanyId()));

                    orderLists.addAll(orderLists1);

                } else {

                    list1.add(sysUser.getCompanyId());
                    List<OrderList> orderLists1 = orderListMapper.queryLime(list1);

                    orderLists.addAll(orderLists1);

                }
//                list1.forEach(e->{
//                    orderList.setCompanyId(e);
//                    List<OrderList> orderLists1 = orderListMapper.queryAllByLimit(orderList);
//                    finalOrderLists.addAll(orderLists1);
//                });
            } else {
                orderLists = orderListMapper.queryAllByLimit(orderList);
            }

        }
        if (radius.contains("2")) {

            boolean allParamsAreNotNull = Stream.of(orderList.getOrderTime(), orderList.getOrderEndTime(), orderList.getOrderSn(), orderList.getCompanyId(), orderList.getOrderType(), orderList.getTagId(), orderList.getComboName(), orderList.getPayStatus()).allMatch(Objects::nonNull);
            if (allParamsAreNotNull) {
                // 对象不为空的处理逻辑
                orderLists = orderListMapper.queryAllByLimit(orderList);

            } else {
                // 对象为空的处理逻辑
                List<Long> collect = sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList());

                List<SysUserCompany> sysUserorderLists = sysUserCompanyMapper.queryAllByLimit(collect);
                List<OrderList> companyVOS1 = new ArrayList<>();
                for (SysUserCompany sysUserCompany : sysUserorderLists) {
                    OrderList orderList1 = new OrderList();
                    orderList1.setCompanyId(sysUserCompany.getId());
                    List<OrderList> companyVOS = orderListMapper.queryAllByLimit(orderList1);
                    companyVOS1.addAll(companyVOS);
                }
                orderLists = companyVOS1;

            }
        }

        for (OrderList e : orderLists) {
            BigDecimal bigDecimal = new BigDecimal(e.getCount());
            BigDecimal multiply = new BigDecimal(e.getAmt());
            BigDecimal multiply1 = multiply.multiply(bigDecimal);
            e.setAmt(String.valueOf(multiply1));
        }
        return orderLists;
    }


    /**
     * 新增数据
     *
     * @param orderList 实例对象
     * @return 实例对象
     */
    @Override
    public OrderList insert(OrderList orderList) {
        orderListMapper.insert(orderList);
        return orderList;
    }

    /**
     * 修改数据
     *
     * @param orderList 实例对象
     * @return 实例对象
     */
    @Override
    public R update(OrderList orderList) {
        orderListMapper.update(orderList);
        return R.ok();
    }

    /**
     * 标记异常
     *
     * @param order
     * @return
     */
    @Override
    public R updateException(OrderList order) {
        OrderList orderList1 = new OrderList();
        orderList1.setId(order.getId());
        OrderList orderList = orderListMapper.queryById(orderList1);
        log.info("查询数据{}", orderList);
        order.setExceptionTime(new Date());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        order.setExceptionOper(loginUser.getSysUser().getNickName());
        order.setUpdateName(loginUser.getSysUser().getNickName());
        if (orderList.getIsExceptionOper() == null || orderList.getIsExceptionOper().equals("0")) {

            order.setIsExceptionOper("1");
        } else {

            order.setIsExceptionOper("0");
        }
        orderListMapper.updateException(order);
        return R.ok();
    }

    @Override
    public void refund(OrderRefundDTO orderRefundDTO) {
        log.info("后台退款查询数据{}", orderRefundDTO);
        OrderList orderLists = orderListMapper.getById(orderRefundDTO.getId());

        if (Objects.isNull(orderLists)) {
            throw new ServiceException(StringUtils.format("订单：{},不存在", orderRefundDTO.getId()));
        }

        if (GoodsTypeEnum.VIRTUAL.getCode().equals(orderLists.getGoodsType())) {
            throw new ServiceException(StringUtils.format("订单：{},为虚拟商品不能退款", orderLists.getOrderSn()));
        }

        if (PayStatusEnum.UNCLAIMED.getCode() == orderLists.getPayStatus()) {

        } else if (PayStatusEnum.COMPLETED.getCode() == orderLists.getPayStatus()) {

        } else if (PayStatusEnum.PAID.getCode() == orderLists.getPayStatus()) {

        } else {
            throw new ServiceException(StringUtils.format("订单：{},退款状态必须是[已完成,未取餐,已付款]", orderLists.getOrderSn()));
        }

        if (Objects.isNull(orderRefundDTO.getAmt())){
            orderRefundDTO.setAmt(NumberUtil.toBigDecimal(orderLists.getAmt()));
        }

        // 已经分账的订单不能退款
        R<Boolean> voidR = remoteOperationService.orderWithdraw(orderLists.getOrderSn());
        if (R.isSuccess(voidR) && !voidR.getData()) {
            throw new ServiceException(StringUtils.format("订单：{},已经分账不能退款", orderLists.getOrderSn()));
        }

        if (PayTypeEnum.WeChatPay.getCode().toString().equals(orderLists.getPayType())) {
            Response<Boolean> booleanResponse = remoteClientService.adminRefund(orderRefundDTO.getId(), orderRefundDTO.getAmt());
            log.info("订单：{},退款结果{}", orderLists.getOrderSn(), booleanResponse);
            if (!booleanResponse.getCode().equals(ResponseEnum.OPERATOR_SUCCESS.getCode())) {
                log.error("订单：{},退款失败{}", orderLists.getOrderSn(), booleanResponse);
                throw new ServiceException(StringUtils.format("订单：{},退款失败，{}", orderLists.getOrderSn(), booleanResponse.getMsg()));
            }
        } else if (PayTypeEnum.BalancePay.getCode().toString().equals(orderLists.getPayType())) {
            Response<Boolean> booleanResponse = remoteClientService.adminBalanceRefund(orderLists.getId(), orderRefundDTO.getAmt());
            log.info("订单：{},退款结果{}", orderLists.getOrderSn(), booleanResponse);
            if (!booleanResponse.getCode().equals(ResponseEnum.OPERATOR_SUCCESS.getCode())) {
                log.error("订单：{},退款失败{}", orderLists.getOrderSn(), booleanResponse);
                throw new ServiceException(StringUtils.format("订单：{},退款失败，{}", orderLists.getOrderSn(), booleanResponse.getMsg()));
            }
        }

        Date date = new Date();
        OrderDetail orderDetails = orderDetailMapper.listByOrderDetailId(orderLists.getId());
        orderDetails.setStatus(PackageStatusEnums.APPLY_REFUND.getStatus());
        orderDetails.setUpdateTime(date);
        orderDetailMapper.updateById(orderDetails);

        orderLists.setPayStatus(PayStatusEnum.REFUNDING.getCode());
        orderLists.setRefundForTime(date);
        orderLists.setRefundReason(orderRefundDTO.getRefundReason());
        orderLists.setUpdateTime(date);
        orderLists.setUpdateName(SecurityUtils.getNickName());
        orderListMapper.updateById(orderLists);

        // 如果是霸王优惠券，模拟微信支付通知客户端退款成功
        remoteClientService.adminRefundNotifyResultSimulate(orderRefundDTO.getId(), orderRefundDTO.getAmt());

        // 退优惠券
        remoteOperationService.refundClientCoupon(orderLists.getId());
    }

    @Override
    public void refundBatch(List<OrderRefundDTO> orderRefundDTOS) {
        for (OrderRefundDTO orderRefundDTO : orderRefundDTOS) {
            orderRefundDTO.setRefundReason("批量退款");
            this.refund(orderRefundDTO);
        }
    }

    @Override
    public List<Tag> tagStatistics(Date startTime, Date endTime) {
        return orderListMapper.tagStatistics(startTime, endTime);
    }

    @Override
    public List<ComboInfo> comboStatistics(Date startTime, Date endTime, String cityName) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.HOUR_OF_DAY, 0);
        calendar.add(Calendar.MINUTE, 0);
        calendar.add(Calendar.SECOND, 0);

        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(endTime);
        calendar1.add(Calendar.HOUR_OF_DAY, 23);
        calendar1.add(Calendar.MINUTE, 59);
        calendar1.add(Calendar.SECOND, 59);
        List<ComboInfo> comboInfos = null;
        ComboStatisticsDTO comboStatisticsDTO = new ComboStatisticsDTO();
        comboStatisticsDTO.setStartTime(calendar.getTime());
        comboStatisticsDTO.setEndTime(calendar1.getTime());
        comboStatisticsDTO.setCompanyId(null);
        comboStatisticsDTO.setCityName(cityName);
        comboInfos = orderListMapper.comboStatistics(comboStatisticsDTO);
        if (CollUtil.isEmpty(comboInfos)) {
            return comboInfos;
        }

        comboInfos.forEach(e -> {
            String num = orderListMapper.queryCoboroad(e.getComboId());
            log.info("查询结果：{}", num, "查询入参：{}", e.getComboId());
            if (num != null) {
                Integer conut = Integer.valueOf(num);
                e.setTotalVolume(String.valueOf(conut));
                if (conut == 0) {
                    e.setSalesProgress(String.valueOf(0));
                } else {
                    long l = Integer.parseInt(e.getSalesVolume()) * 100L / conut;
                    e.setSalesProgress(String.valueOf(l));
                }
            } else {
                e.setTotalVolume("0");
                e.setSalesProgress("0");
            }
        });

        return comboInfos;
    }

    @Override
    public R calculate(String orderId) {
        OrderList orderList = new OrderList();
        orderList.setOrderSn(orderId);
        List<OrderList> orderLists = orderListMapper.queryLimit(orderList);
        log.info("查询结果{}", orderLists);
        BigDecimal bigDecimal1 = new BigDecimal(0);
        if (orderLists.get(0).getOrderType().equals("0")) {
            for (OrderList list : orderLists) {
                BigDecimal bigDecimal = new BigDecimal(list.getAmt());
                bigDecimal1 = bigDecimal1.add(bigDecimal);
            }
        } else {
            bigDecimal1 = new BigDecimal(orderLists.get(0).getAmt());
        }

        HashMap<String, Object> orderMap = new HashMap<>();
        orderMap.put("amt", bigDecimal1);
        orderMap.put("orderId", orderId);
        return R.ok(orderMap);
    }
}
